﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.DirectoryServices.AccountManagement;
using VPLink2014.Data;
using VPLink2014.Data.MesApplis;

namespace VPLink2013.Batch
{
    public class Program
    {
        private static StringBuilder sbTrace;

        #region Helper
        private static void SaveTrace(string fileName)
        {
            try
            {
                string strPath = System.Environment.CurrentDirectory + @"\" + fileName;
                System.IO.File.WriteAllText(strPath, sbTrace.ToString(), Encoding.UTF8);
                sbTrace = new StringBuilder();
            }
            catch (System.Exception exc)
            {
                Console.WriteLine(exc.Message);
                sbTrace.AppendLine(string.Format(" Exception : message {0} trace : {1}", exc.Message, exc.StackTrace));
            }
        }


        private static int getAppliIdByName(string applicationTitle)
        {
            int appId = -1;
            try
            {
                using (VPLinkLogConnection db = new VPLinkLogConnection())
                {
                    Application appDb = (from u in db.VplinkEntities.Applications
                                          where u.titre == applicationTitle
                                          select u).FirstOrDefault();
                    if (appDb != null)
                    {
                        appId = appDb.id;
                    }
                    else
                    {
                        Console.WriteLine("L'application {0} n'a pas été trouvé", applicationTitle);
                        sbTrace.AppendLine(string.Format("l'application {0} n' pas a été trouvé", applicationTitle));
                    }
                }
            }
            catch (Exception ex)
            {
                sbTrace.AppendLine(string.Format(" Exception : message {0} trace : {1}", ex.Message, ex.StackTrace));
            }
            return appId;
        }
        #endregion

        public static void Main(string[] args)
        {
            sbTrace = new StringBuilder();
            Console.WriteLine("1 - Par liste de distribution\n2 - Par utilisateur\n3 - Par équipe");
            string appTitle = string.Empty;
            int appliId = -1;

            string choix = Console.ReadLine();
            switch (choix)
            {
                case "1":
                    {
                        while (appliId == -1)
                        {
                            Console.WriteLine("Nom de l'application:");
                            appTitle = Console.ReadLine();
                            appliId = getAppliIdByName(appTitle);
                        }

                        Console.WriteLine("Nom de la liste :");
                        string listName = Console.ReadLine();

                        AttachListToApplication(listName, appliId);
                        SaveTrace(string.Format("trace_{0}_{1}.txt", listName, appTitle));
                        break;
                    }
                case "2":
                    {
                        while (appliId == -1)
                        {
                            Console.WriteLine("Nom de l'application:");
                            appTitle = Console.ReadLine();
                            appliId = getAppliIdByName(appTitle);
                        }
                        Console.WriteLine("User login:");
                        string userLogin = Console.ReadLine();

                        AttachUserToApplication(userLogin, appliId);
                        SaveTrace(string.Format("trace_{0}_{1}.txt", userLogin.Replace("oredis-vp\\", string.Empty), appTitle));
                        break;
                    }
                case "3":
                    {
                        while (appliId == -1)
                        {
                            Console.WriteLine("Nom de l'application:");
                            appTitle = Console.ReadLine();
                            appliId = getAppliIdByName(appTitle);
                        }
                        Console.WriteLine("Type d'équipe : (1-direction 2- departement 3- service)");
                        int teamType = Int32.Parse(Console.ReadLine());

                        //Console.WriteLine( "Récursive (oui/non)" );
                        //bool recursive = string.Compare(Console.ReadLine(), "oui",StringComparison.CurrentCultureIgnoreCase) == 0 ? true : false;

                        Console.WriteLine("Nom de l'équipe:");
                        string teamName = Console.ReadLine();

                        AttachTeamToApplication(teamType, teamName, appliId);
                        SaveTrace(string.Format("trace_{0}_{1}.txt", teamName, appTitle));
                        break;
                    }
                default: break;
            }
        }

        private static void treatPrincipal(int applicationID, VPLinkLogConnection db, Principal p)
        {
            UserPrincipal user = p as UserPrincipal;
            if (user != null)
            {
                string userLogin = string.Format("oredis-vp\\{0}", user.SamAccountName);
                AddApplicationToUser(applicationID, db, userLogin);
            }
            else
            {
                GroupPrincipal group = p as GroupPrincipal;
                if (group != null)
                {
                    sbTrace.AppendLine(string.Format("Traitement du sous groupre {0}", group.Name));
                    PrincipalSearchResult<Principal> members = group.GetMembers();
                    foreach (Principal member in members)
                    {
                        treatPrincipal(applicationID, db, member);
                    }
                }
            }
        }

        public static void AttachTeamToApplication(int teamType, string teamName, int applId)
        {
            List<VOApplication> listAppl = new List<VOApplication>();
            try
            {
                switch (teamType)
                {
                    case 1:
                        {
                            #region Direction
                            VODirectionMapper dir = new VODirectionMapper(teamName);
                            if (dir.direction != null)
                            {
                                Console.WriteLine("L'équipe {0} a été trouvé", teamName);
                                using (VPLinkLogConnection db = new VPLinkLogConnection())
                                {
                                    foreach (var app in db.VplinkEntities.GetDirectionApplications(teamName))
                                    {
                                        listAppl.Add(new VOApplication() { Id = app.id });
                                    }
                                }
                                if (!listAppl.Any(x => x.Id == applId))
                                {
                                    listAppl.Add(new VOApplication() { Id = applId });
                                    Console.WriteLine("Traitement...");
                                    dir.SetApplications(listAppl);
                                    Console.WriteLine("Ajout réussi.");
                                    sbTrace.AppendLine(string.Format("l'application a été rajouté à l'équipe {0}", teamName));
                                }
                                else
                                {
                                    Console.WriteLine("L'équipe  {0} a déjà l'application", teamName);
                                    sbTrace.AppendLine(string.Format("L'équipe  {0} a déjà l'application", teamName));
                                }
                            }
                            else
                            {
                                Console.WriteLine("L'équipe {0} n'a pas été trouvé", teamName);
                                sbTrace.AppendLine(string.Format("l'équipe {0} n' pas a été trouvé", teamName));
                            }
                            break;
                            #endregion
                        }
                    case 2:
                        {
                            #region Departement
                            VODepartementMapper dept = new VODepartementMapper(teamName);
                            if (dept.departement != null)
                            {
                                Console.WriteLine("L'équipe {0} a été trouvé", teamName);
                                using (VPLinkLogConnection db = new VPLinkLogConnection())
                                {
                                    foreach (var app in db.VplinkEntities.GetDepartementApplications(teamName))
                                    {
                                        listAppl.Add(new VOApplication() { Id = app.id });
                                    }
                                }
                                if (!listAppl.Any(x => x.Id == applId))
                                {
                                    listAppl.Add(new VOApplication() { Id = applId });
                                    Console.WriteLine("Traitement...");
                                    dept.SetApplications(listAppl);
                                    Console.WriteLine("Ajout réussi.");
                                    sbTrace.AppendLine(string.Format("l'application {0} a été rajouté à l'équipe ", teamName));
                                }
                                else
                                {
                                    Console.WriteLine("L'équipe {0} n'a pas été trouvé", teamName);
                                    sbTrace.AppendLine(string.Format("l'équipe {0} n' pas a été trouvé", teamName));
                                }
                            }
                            else
                            {
                                Console.WriteLine("L'équipe {0} n'a pas été trouvé", teamName);
                                sbTrace.AppendLine(string.Format("l'équipe {0} n' pas a été trouvé", teamName));
                            }
                            break;
                            #endregion
                        }
                    case 3:
                        {
                            #region Service
                            VOServiceMapper sce = new VOServiceMapper(teamName);
                            if (sce.service != null)
                            {
                                Console.WriteLine("L'équipe {0} a été trouvé", teamName);
                                using (VPLinkLogConnection db = new VPLinkLogConnection())
                                {
                                    foreach (var app in db.VplinkEntities.GetServiceApplications(teamName))
                                    {
                                        listAppl.Add(new VOApplication() { Id = app.id });
                                    }
                                }
                                if (!listAppl.Any(x => x.Id == applId))
                                {
                                    listAppl.Add(new VOApplication() { Id = applId });
                                    Console.WriteLine("Traitement...");
                                    sce.SetApplications(listAppl);
                                    Console.WriteLine("Ajout réussi.");
                                    sbTrace.AppendLine(string.Format("l'application a été rajouté à l'équipe {0}", teamName));
                                }
                                else
                                {
                                    Console.WriteLine("L'équipe {0} n'a pas été trouvé", teamName);
                                    sbTrace.AppendLine(string.Format("l'équipe {0} n' pas a été trouvé", teamName));
                                }
                            }
                            else
                            {
                                Console.WriteLine("L'équipe {0} n'a pas été trouvé", teamName);
                                sbTrace.AppendLine(string.Format("l'équipe {0} n' pas a été trouvé", teamName));
                            }
                            break;
                            #endregion
                        }
                    default: break;
                }
            }
            catch (Exception ex)
            {
                sbTrace.AppendLine(string.Format(" Exception : message {0} trace : {1}", ex.Message, ex.StackTrace));
            }
        }


        private static void AddApplicationToUser(int applicationID, VPLinkLogConnection db, string userLogin)
        {
            VOUserMapper user = new VOUserMapper(userLogin);
            if (user.user != null)
            {
                sbTrace.AppendLine(string.Format("Traitement de : {0}", userLogin));
                List<VOApplication> applications = new List<VOApplication>();
                foreach (var app in db.VplinkEntities.GetSelectedApplicationsForUser(userLogin))
                {
                    applications.Add(new VOApplication()
                    {
                        Id = app.id
                    });
                }
                if (!applications.Any(x => x.Id == applicationID))
                {
                    applications.Add(new VOApplication()
                    {
                        Id = applicationID
                    });
                    user.SetApplications(applications);
                    sbTrace.AppendLine(string.Format("ajout application {0} réussi", applicationID));
                }
                else
                {
                    Console.WriteLine(string.Format("L'utilisateur {0} a déja lapplication {1}", userLogin, applicationID));
                    sbTrace.AppendLine(string.Format("L'utilisateur {0} a déja lapplication {1}", userLogin, applicationID));
                }
            }
            else
            {
                Console.WriteLine(string.Format("L'utilisateur {0} n'a pas été trouvé dans la base", userLogin));
                sbTrace.AppendLine(string.Format("L'utilisateur {0} n'a pas été trouvé dans la base", userLogin));
            }
        }

        public static void AttachListToApplication(string distributionGroup, int applicationID)
        {
            PrincipalContext ctx = new PrincipalContext(ContextType.Domain);
            GroupPrincipal group = GroupPrincipal.FindByIdentity(ctx, distributionGroup);
            if (group != null)
            {
                PrincipalSearchResult<Principal> members = group.GetMembers();
                sbTrace.AppendLine(string.Format("il y a {0} membres dans la liste de distribution {1}", members.Count(), distributionGroup));
                try
                {
                    //using (VPLinkLogConnection db = new VPLinkLogConnection())
                    //{
                    //    foreach (Principal member in members)
                    //    {
                    //        treatPrincipal(applicationID, db, member);
                    //    }
                    //}
                }
                catch (Exception e)
                {
                    sbTrace.AppendLine(string.Format(" Exception : message {0} trace : {1}", e.Message, e.StackTrace));
                }
            }
            else
            {
                Console.WriteLine("La liste de distribution n'existe pas");
                sbTrace.AppendLine(string.Format("La liste de distribution {0} n'existe pas", distributionGroup));
            }
        }

        private static void AttachUserToApplication(string userLogin, int applicationID)
        {
            try
            {
                //using (VPLinkLogConnection db = new VPLinkLogConnection())
                //{
                //    List<MyApplicationsManager.Repository.VOApplication> applications = new List<MyApplicationsManager.Repository.VOApplication>();
                //    AddApplicationToUser(applicationID, db, userLogin);
                //}
            }
            catch (Exception e)
            {
                sbTrace.AppendLine(string.Format(" Exception : message {0} trace : {1}", e.Message, e.StackTrace));
            }
        }
    }
}
